const { create } = require('../helper/db');
const { decrypt } = require('../helper/util');

const chatMap = {};


/**
 * @apiDefine ErrorResponse
 * @apiError (请求错误) {String} err_message 错误信息描述
 */

/**
 * @apiVersion 1.0.0
 * @apiGroup  聊天
 * @api {WS} chat 聊天通道
 * @apiName /chat
 * @apiExample {js} socket.io-client 例子:
 *  import socket from 'socket.io-client';
 *  
 *  const chat = socket.connect('ws://localhost:8080/chat');
 *  
 *  chat.on('connect', () => {
 *    // 连接成功, 可以在这里面监听或者触发事件;
 *  });
 */

/**
 * @apiVersion 1.0.0
 * @apiGroup  聊天
 * @api {WS} / 触发 join 事件
 * @apiName join
 * @apiExample {js} socket.io-client 例子:
 *  import socket from 'socket.io-client';
 *  
 *  const chat = socket.connect('ws://localhost:8080/chat');
 *  
 *  // 连接成功, 可以在这里面监听或者触发事件;
 *  chat.on('connect', () => {
 *    // 触发 join 事件，目的是通知服务端连接就绪，可以接受聊天消息了;
 *    chat.emit('join', { token });
 *  });
 * @apiParam {String} token 用户令牌
 */

/**
 * @apiVersion 1.0.0
 * @apiGroup  聊天
 * @api {WS} / 监听 ok 事件
 * @apiName ok
 * @apiExample {js} socket.io-client 例子:
 *  import socket from 'socket.io-client';
 *  
 *  const chat = socket.connect('ws://localhost:8080/chat');
 *  
 *  // 连接成功, 可以在这里面监听或者触发事件;
 *  chat.on('connect', () => {
 *    // 服务端接受到客户端的 join 事件后，会往客户端发送 ok 事件，代表服务端已经知晓了客户端的加入；
 *    chat.on('ok', (data) => {});
 *  });
 * @apiParam (数据) {Null} data 没有数据
 */

/**
 * @apiVersion 1.0.0
 * @apiGroup  聊天
 * @api {WS} / 触发 message 事件
 * @apiName message
 * @apiExample {js} socket.io-client 例子:
 *  import socket from 'socket.io-client';
 *  
 *  const chat = socket.connect('ws://localhost:8080/chat');
 *  
 *  // 连接成功, 可以在这里面监听或者触发事件;
 *  chat.on('connect', () => {
 *    // 触发 message 事件, 可以向好友发送消息
 *    chat.emit('message', { token, toUserID, kind, data });
 *  });
 * @apiParam {String} token 用户令牌
 * @apiParam {Number} toUserID 向哪位好友发送消息
 * @apiParam {Number} kind 消息类型: 1 文字消息, 2 语音消息, 3 视频消息
 * @apiParam {Object} data 消息主体
 */

/**
 * @apiVersion 1.0.0
 * @apiGroup  聊天
 * @api {WS} / 监听 message 事件
 * @apiName onmessage
 * @apiExample {js} socket.io-client 例子:
 *  import socket from 'socket.io-client';
 *  
 *  const chat = socket.connect('ws://localhost:8080/chat');
 *  
 *  // 连接成功, 可以在这里面监听或者触发事件;
 *  chat.on('connect', () => {
 *    // 通知的通道有新消息时会触发 message 事件，客户端监听 message 事件可以在事件回调函数中获取数据
 *    chat.on('message', (data) => {});
 *  });
 * @apiParam (数据) {Number} kind 消息类型: 1 文字聊天， 2 语音聊天， 3 视频聊天
 * @apiParam (数据) {Object} data 消息主体
 * @apiParam (数据) {Number} fromUserID 消息来自哪位好友
 */

module.exports = (socket) => {
  // 用户进入时保留用户的连接 id;
  socket.on('join', data => {
    const userid = decrypt('user', data.token);
    chatMap[userid] = socket.id;
    socket.emit('ok');
  });

  // 连接断开时将用户踢出 map
  socket.on('disconnect', () => {
    for (let key in chatMap) {
      if (chatMap[key] === socket.id) {
        chatMap[key] = null;
      }
    }
  });
  
  socket.on('message', data => {
    console.log(data);
    const socketID = chatMap[`${data.toUserID}`];
    const fromUserID = decrypt('user', data.token);

    console.log(chatMap);
    console.log(socketID);

    // 如果要发送给消息的用户在 map 中直接发送消息，不在则不发
    if (!socketID) return;

    socket.broadcast.to(socketID).emit('message', {
      fromUserID: fromUserID,
      kind: data.kind, // 1 文字消息， 2 语音通话  3 视频通话
      data: data.data,
    });
  });
};
